/**
 *	@brief	ポケギアスキン BG描画
 *	@author	Miyuki Iwasawa
 *	@date	07.06.20
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "gflib/touchpanel.h"
#include "field/field_matrix.h"
#include "field/field_place_name.h"
#include "application/app_tool.h"
#include "application/pokegear.h"
#include "msgdata/msg.naix"

#include "../pgear_sys.h"
#include "../pgear_frm.h"
#include "../pgear_act.h"
#include "pgskin_sys.h"
#include "pgskin_sub.h"

#define __BGSKIN_BG_H_GLOBAL
#include "pgskin_bg.h"

#include "msgdata/msg_pg_skin.h"

//===========================================================================
///プロトタイプ
//===========================================================================
static void pgskin_BGLInit(PGSKIN_SYS_WORK* wk);
static void pgskin_BGLRelease(PGSKIN_SYS_WORK* wk);
static void pgskin_2DResInit(PGSKIN_SYS_WORK* wk);
static void pgskin_2DResRelease(PGSKIN_SYS_WORK* wk);
static void pgskin_ActResInit(PGSKIN_SYS_WORK* wk);
static void pgskin_ActResRelease(PGSKIN_SYS_WORK* wk);
static void pgskin_MakeActor(PGSKIN_SYS_WORK* wk);
static void pgskin_DelActor(PGSKIN_SYS_WORK* wk);
static void pgskin_CMoveParamInit(PGSKIN_SYS_WORK* wk);
static void pgskin_CMoveParamRelease(PGSKIN_SYS_WORK* wk);
static void pgskin_SelBoxListInit(PGSKIN_SYS_WORK* wk);
static void pgskin_SelBoxListDelete(PGSKIN_SYS_WORK* wk);
static void pgskin_IniDraw(PGSKIN_SYS_WORK* wk);

//===========================================================================
///プログラムエリア
//===========================================================================
/**
 *	@brief	マップの初期化
 */
int PGSkin_AppInit(PGSKIN_SYS_WORK* wk)
{
	switch(wk->sub_seq){
	case 0:
		pgskin_BGLInit(wk);
		pgskin_2DResInit(wk);
		pgskin_ActResInit(wk);
		//OBJ実体作成前にパレットアニメワークを登録
		PGSkinSub_PalAnmWorkSet(wk,TRUE);
		break;
	case 1:
		pgskin_MakeActor(wk);
		pgskin_CMoveParamInit(wk);
		pgskin_SelBoxListInit(wk);
		pgskin_IniDraw(wk);

		//アプリVBlank関数登録
//		wk->sys->app_vfunc = PGSkinSub_VBlank;

		wk->sub_seq = 0;
		return TRUE;
	}
	++wk->sub_seq;
	return FALSE;
}

/**
 *	@brief	マップの開放
 */
int PGSkin_AppEnd(PGSKIN_SYS_WORK* wk)
{
	pgskin_SelBoxListDelete(wk);
	pgskin_CMoveParamRelease(wk);
	pgskin_DelActor(wk);
	pgskin_ActResRelease(wk);
	pgskin_2DResRelease(wk);
	pgskin_BGLRelease(wk);
	return TRUE;
}

/**
 *	@brief	スキンの変更選択
 */
int PGSkin_SkinSelect(PGSKIN_SYS_WORK* wk)
{
	u32 ret;

	ret = SelectBoxMain(wk->list_wk);
	if(ret != SBOX_SELECT_NULL){
		wk->sys->key_mode = SelectBoxGetKTStatus(wk->list_wk);

		SelectBoxExit(wk->list_wk);
		PGSkinSub_WindowMaskSet(wk,0,FALSE);
		CursorMvMan_SetAnmFlagIdx(wk->sys->curMan,CURMV_CURRENT,TRUE);

		if(	ret == 0){
			return PGSKIN_SEQ_SKIN_CHANGE;
		}
		return PGSKIN_SEQ_MAIN;
	}
	return PGSKIN_SEQ_SKIN_SELECT;
}

/**
 *	@brief	新しいスキンの再セット
 */
static void skinbg_ResChange(PGSKIN_SYS_WORK* wk)
{
#if 1
	PGSkinSub_2DResRelease(wk);

	wk->skin = wk->tmpSkin;
	wk->sys->skin_id = wk->skin;
	IWASAWA_PRINT(" SkinChange = %d\n",wk->skin);

	//システムリソース読み替え
	PGFrame_2DResLoad(wk->sys,wk->skin);
	PGSysOam_ResChange(wk->sys->pSysOam,wk->skin);

	PGSkinSub_2DResInit(wk);
	PGSkinSub_PalAnmWorkSet(wk,FALSE);
#endif
	//再描画
	PGSkinSub_BackDraw(wk);
	PGSkinSub_SelectSkinChange(wk,wk->skin);
}

/**
 *	@brief	スキンの交換
 */
int PGSkin_SkinChange(PGSKIN_SYS_WORK* wk)
{
	switch(wk->sub_seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_FMAS,
			WIPE_TYPE_SHUTTEROUT_UP,
			WIPE_TYPE_SHUTTEROUT_UP,0x0000,6,1,wk->heapID
			);
		break;
	case 1:
		//フェード待ち
		if(!WIPE_SYS_EndCheck()){
			return FALSE;
		}
		//リソース読み替え
		skinbg_ResChange(wk);
		break;
	case 2:
		WIPE_SYS_Start(WIPE_PATTERN_FSAM,
			WIPE_TYPE_SHUTTERIN_DOWN,
			WIPE_TYPE_SHUTTERIN_DOWN,0x0000,6,1,wk->heapID
			);
		break;
	case 3:
		//フェード待ち
		if(!WIPE_SYS_EndCheck()){
			return FALSE;
		}
		wk->sub_seq = 0;
		return TRUE;
	}
	++wk->sub_seq;
	return FALSE;
}



/**
 *	@brief	マップのBGL初期化
 */
static void pgskin_BGLInit(PGSKIN_SYS_WORK* wk)
{
	int i;
	GF_BGL_INI* bgl = wk->sys->bgl;

	//メインのBGモードをtext,text,affineEx,affineExのMode5に変更
	{
#if 0
		GF_BGL_SYS_HEADER BGsys_data = {
			GX_DISPMODE_GRAPHICS,GX_BGMODE_5,GX_BGMODE_0,GX_BG0_AS_2D
		};
		GF_BGL_InitBGDisp(&BGsys_data,GF_BGL_MAIN_DISP);
#endif
		//GFルールでは直接呼ぶべきではないが、ポケギアでは特別に呼ぶ
		GX_SetGraphicsMode( GX_DISPMODE_GRAPHICS, GX_BGMODE_0,GX_BG0_AS_2D );
	}

	{	//BG0はフレームの占有領域なのでいじらないこと！
		GF_BGL_BGCNT_HEADER TextBgCntDat[] = {
		{	//MAIN BG1
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000,GX_BG_CHARBASE_0x10000,GX_BG_EXTPLTT_01,
			1,0,0,FALSE},
		{	//MAIN BG2
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			2,0,0,FALSE},
		{	//MAIN BG3
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe000,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			3,0,0,FALSE},
		{	//SUB BG1
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			0,0,0,FALSE},
		{	//SUB BG2
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			1,0,0,FALSE},
		{	//SUB BG3
			0,0,0x800,0,GF_BGL_SCRSIZ_256x256,GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe000,GX_BG_CHARBASE_0x00000,GX_BG_EXTPLTT_01,
			2,0,0,FALSE},
		};
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME1_M,&(TextBgCntDat[0]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME2_M,&(TextBgCntDat[1]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME3_M,&(TextBgCntDat[2]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME1_S,&(TextBgCntDat[3]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME2_S,&(TextBgCntDat[4]),GF_BGL_MODE_TEXT,VISIBLE_OFF);
		GF_BGL_BGControlSetEx(wk->sys->bgl,GF_BGL_FRAME3_S,&(TextBgCntDat[5]),GF_BGL_MODE_TEXT,VISIBLE_OFF);

		for(i = 0;i < 3;i++){
			GF_BGL_ScrClear(wk->sys->bgl,GF_BGL_FRAME1_M+i);
			GF_BGL_ClearCharSet(GF_BGL_FRAME1_M+i,32,0,wk->heapID);
			GF_BGL_ScrClear(wk->sys->bgl,GF_BGL_FRAME1_S+i);
			GF_BGL_ClearCharSet(GF_BGL_FRAME1_S+i,32,0,wk->heapID);
		}
	}

}

/**
 *	@brief	マップBGL開放
 *
 */
static void pgskin_BGLRelease(PGSKIN_SYS_WORK* wk)
{
	PGFrame_LocalVramClear(wk->sys);
#if 0
	//ローカルパレット領域をクリア
	GF_BGL_ClearPaletteSet(GF_BGL_FRAME3_M,0x20*PGAPP_PALNUM_M,0 ,wk->heapID);
	GF_BGL_ClearPaletteSet(GF_BGL_FRAME3_M,0x20*PGAPP_PALNUM_S,0 ,wk->heapID);

	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME3_S);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME2_S);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME1_S);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME3_M);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME2_M);
	GF_BGL_BGControlExit( wk->sys->bgl,GF_BGL_FRAME1_M);
#endif
}

/**
 *	@brief	スキンのBGリソース初期化
 */
static void pgskin_2DResInit(PGSKIN_SYS_WORK* wk)
{
	//ここでタッチフォントも追加しておく
	FontProc_LoadFont( FONT_TOUCH, wk->heapID );

	//リソースVRAM転送
	PGSkinSub_2DResInit(wk);
}

/**
 *	@brief	スキンのBGリソース開放
 */
static void pgskin_2DResRelease(PGSKIN_SYS_WORK* wk)
{
	//リソース開放
	PGSkinSub_2DResRelease(wk);

	FontProc_UnloadFont( FONT_TOUCH );
}

/**
 *	@brief	スキンのアクターリソース初期化
 */
static void pgskin_ActResInit(PGSKIN_SYS_WORK* wk)
{
	//リソース確保
	PGear_ActorResInit(wk->sys,PGAPP_MODE_SKIN);

	wk->sbox = SelectBoxSys_AllocWork(wk->heapID,wk->sys->palAnm);
}

/**
 *	@brief	スキンのアクターリソース開放
 */
static void pgskin_ActResRelease(PGSKIN_SYS_WORK* wk)
{
	//リソース開放
	SelectBoxSys_Free(wk->sbox);
	PGear_ActorResRelease(wk->sys);
}

/**
 *	@brief	ノーマルOBJの作成
 */
static void pgskin_MakeActor(PGSKIN_SYS_WORK* wk)
{
	int i;
	u16	idx;
//	PGEAR_ACT_WORK*  pAct= wk->pActWMan->pAct;

	static const TCATS_OBJECT_ADD_PARAM	ActAddParam[] =
	{
		{	// カーソル
			RESACT_SKOAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_CLU, 1, PGSYSOAM_PALNUM_M+2, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// カーソル
			RESACT_SKOAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_CLD, 1, PGSYSOAM_PALNUM_M+2, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// カーソル
			RESACT_SKOAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_CRU, 1, PGSYSOAM_PALNUM_M+2, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// カーソル
			RESACT_SKOAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_CRD, 1, PGSYSOAM_PALNUM_M+2, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// NEWマーク
			RESACT_SKOAM,	//ID
			0, 0, 0,	//x,y,z
			ANM_H_NEW, 1, PGSYSOAM_PALNUM_M+0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			0, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
	};
	for(i = 0;i <= SKACT_NEW;i++){
		wk->pAct[i] = CATS_ObjectAdd( wk->sys->pActSys,wk->sys->pActRes,&ActAddParam[i]);
		CATS_ObjectBGPriSet(wk->pAct[i],1);
		CLACT_SetDrawFlag(wk->pAct[i], FALSE);
		CLACT_SetAnmFlag(wk->pAct[i], TRUE);
	}
	//選択ボックス用アクター
	for(i = SKACT_SBCLU; i <= SKACT_SBCRD;i++){
		wk->pAct[i] = CATS_ObjectAdd( wk->sys->pActSys,wk->sys->pActRes,&ActAddParam[i-SKACT_SBCLU]);
		CATS_ObjectBGPriSet(wk->pAct[i],1);
		CATS_ObjectPriSet(wk->pAct[i],0);
		CLACT_SetDrawFlag(wk->pAct[i], FALSE);
		CLACT_SetAnmFlag(wk->pAct[i], FALSE);
	}
}

/**
 *	@brief	ノーマルOBJの開放
 */
static void pgskin_DelActor(PGSKIN_SYS_WORK* wk)
{
	int i;

	for(i = 0;i < SKACT_MAX;i++){
		CATS_ObjectDel(wk->pAct[i]);
	}
}

/**
 *	@brief	カーソル移動パラメータ登録
 */
static void pgskin_CMoveParamInit(PGSKIN_SYS_WORK* wk)
{
	static const CURSORMV_DAT_UNIT skin_keycnt[] = {
	//id, left,right,up,down,
	 {0, 2,1, 3,3, SM01_DPX+SM_DSX_H,SM01_DPY+SM_DSY_H,-(SM_DSX_H-2),(SM_DSX_H-2),-(SM_DSY_H-2),(SM_DSY_H-2)},
	 {1, 0,2, 4,4, SM02_DPX+SM_DSX_H,SM02_DPY+SM_DSY_H,-(SM_DSX_H-2),(SM_DSX_H-2),-(SM_DSY_H-2),(SM_DSY_H-2)},
	 {2, 1,0, 5,5, SM03_DPX+SM_DSX_H,SM03_DPY+SM_DSY_H,-(SM_DSX_H-2),(SM_DSX_H-2),-(SM_DSY_H-2),(SM_DSY_H-2)},

	 {3, 5,4, 0,0, SM04_DPX+SM_DSX_H,SM04_DPY+SM_DSY_H,-(SM_DSX_H-2),(SM_DSX_H-2),-(SM_DSY_H-2),(SM_DSY_H-2)},
	 {4, 3,5, 1,1, SM05_DPX+SM_DSX_H,SM05_DPY+SM_DSY_H,-(SM_DSX_H-2),(SM_DSX_H-2),-(SM_DSY_H-2),(SM_DSY_H-2)},
	 {5, 4,3, 2,2, SM06_DPX+SM_DSX_H,SM06_DPY+SM_DSY_H,-(SM_DSX_H-2),(SM_DSX_H-2),-(SM_DSY_H-2),(SM_DSY_H-2)},
	};

	CursorMvMan_EntryParamUnit(wk->sys->curMan,skin_keycnt,NELEMS(skin_keycnt),
		0,CURMV_OAM_CLACT,wk->heapID,
		(void*)wk->pAct[SKACT_CLU],(void*)wk->pAct[SKACT_CLD],
		(void*)wk->pAct[SKACT_CRU],(void*)wk->pAct[SKACT_CRD]);

	//いったん非表示
	CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,PGKM_APP_PARAM1,FALSE);
}

/**
 *	@brief	カーソル移動パラメータ開放
 */
static void pgskin_CMoveParamRelease(PGSKIN_SYS_WORK* wk)
{
	CursorMvMan_DeleteParam(wk->sys->curMan,PGKM_APP_PARAM1);
}

/**
 *	@brief	選択ボックスリストの初期化
 */
static void pgskin_SelBoxListInit(PGSKIN_SYS_WORK* wk)
{
	int i;
	MSGDATA_MANAGER *msg;

	//BMPリスト領域作成
	wk->plist = BMP_MENULIST_Create(2,wk->heapID);

	msg = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,NARC_msg_pg_skin_dat,wk->heapID);

	for(i = 0;i < 2;i++){
		BMP_MENULIST_AddArchiveString(wk->plist,msg,msg_change+i,i);
	}

	MSGMAN_Delete(msg);
}

/**
 *	@brief	選択ボックスリストの解放
 */
static void pgskin_SelBoxListDelete(PGSKIN_SYS_WORK* wk)
{
	//リスト解放
//	BmpListExit(wk->plist_wk,&(wk->listPos),&(wk->curPos));
	BMP_MENULIST_Delete(wk->plist);

	wk->plist = NULL;
}

/*
 *	@brief	初期画面描画
 */
static void pgskin_IniDraw(PGSKIN_SYS_WORK* wk)
{
	PGSkinSub_BackDraw(wk);

	//キー操作モードによって、描画状態を変更
	if(wk->sys->control == PGCONT_SYS){
		CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,PGKM_SYS_PARAM,TRUE);
		CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,PGKM_APP_PARAM1,FALSE);
		CursorMvMan_SetCurrent(wk->sys->curMan,PGKM_SYS_PARAM,
				PGFrame_GetSCurModePosNo(wk->sys));
	}else{
		CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,PGKM_SYS_PARAM,FALSE);
		CursorMvMan_SetCursorDrawFlag(wk->sys->curMan,PGKM_APP_PARAM1,TRUE);
		CursorMvMan_SetCurrent(wk->sys->curMan,PGKM_APP_PARAM1,0);
	}
}
